package com.vanvalt.payhui.modules.pay.api;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.google.common.collect.Maps;
import com.thinkgem.jeesite.common.config.Global;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.service.SystemService;
import com.vanvalt.payhui.modules.pay.api.command.impl.ResponseCommand;
import com.vanvalt.payhui.modules.pay.api.util.CommandCode;
import com.vanvalt.payhui.modules.pay.api.util.ErrorCode;
import com.vanvalt.payhui.util.json.JsonConversion;

@Controller
@Scope("prototype")
@RequestMapping(value = "/api")
public class Upload {
	
	/**
	 * 日志.
	 */
	private static Logger					logger				= Logger.getLogger(Upload.class);
	private HttpServletRequest 				request;
    private HttpServletResponse 			response;
	private static final String				CONTENT_TYPE		= "Content-Type";
	private static final String				APPLICATION_CHARSET	= "application/json; charset=utf-8";
	private static final String				CHARSET				= "utf-8";
	
	/**
	 * 输出。
	 */
	private String							output;
	
	@Autowired
	private SystemService					systemService;
	
	@POST
	@Consumes(MediaType.MULTIPART_FORM_DATA)
	@Produces("application/json;charset=UTF-8")
	@ResponseBody
	@RequestMapping(value = "upload", produces="application/octet-stream")
	public void upload(@RequestParam("uid") String uid, 
			@RequestParam("file") MultipartFile file,
			@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException {
		
		ResponseCommand responseCommand = new ResponseCommand();
		responseCommand.setCommand(String.valueOf(CommandCode.CMD_MEMBER_HEAD_CHANGE));
		
		if(StringUtils.isBlank(uid) && file.isEmpty()){
			responseCommand = this.returnResult(ErrorCode.ERR_CODE_STATUS_FALSE, ErrorCode.ERR_CODE_PRECONDITION_FAILED, responseCommand);
		} else {
			
			User user = systemService.getUser(uid);
			
			if(user == null){
				responseCommand = this.returnResult(ErrorCode.ERR_CODE_STATUS_FALSE, ErrorCode.ERR_CODE_PRECONDITION_FAILED_USER_NOT_EXIST, responseCommand);
			} else {
				
				String newName = "";
				
				Map<String,Object> map = Maps.newHashMap();
				
				try {
					String originalFilename = file.getOriginalFilename();
					newName = this.getNewName(originalFilename, "head");
					
					// 头像上传路径
					String uploadPath = Global.getConfig("web.file.upload.path");
					String headPath = "/userfiles/head";
					
					initDirectory(uploadPath+headPath);
					String filePath = uploadPath + headPath + "/" + newName;
					
					file.transferTo(new File(filePath));
					// 保存个人头像
					String photo = headPath + "/" + newName;
					user.setPhoto(photo);
					user.setUpdateBy(user);
					user.setUpdateDate(new Date());
					
					systemService.saveUser(user);
					
					// 头像下载路径
					String downloadPath = Global.getConfig("web.file.download.url");
					String fileDownloadPath = downloadPath + headPath + "/" + newName;
					
					map.put("uid", uid);
					map.put("fileName", newName);
					map.put("originalFileName", originalFilename);
					map.put("filePath", fileDownloadPath);
					
					responseCommand = this.returnResult(ErrorCode.ERR_CODE_STATUS_TRUE, ErrorCode.ERR_CODE_SUCCESS, JsonConversion.writeMapJSON(map), responseCommand);
				} catch (IllegalStateException e) {
					e.printStackTrace();
					responseCommand = this.returnResult(ErrorCode.ERR_CODE_STATUS_FALSE, ErrorCode.ERR_CODE_EXCEPTION, responseCommand);
				} catch (IOException e) {
					e.printStackTrace();
					responseCommand = this.returnResult(ErrorCode.ERR_CODE_STATUS_FALSE, ErrorCode.ERR_CODE_EXCEPTION, responseCommand);
				}
			}
		}
		
		
		output = responseCommand.toJson();
		
		response.setContentType(CONTENT_TYPE);
		response.setCharacterEncoding(CHARSET);
		PrintWriter out = response.getWriter();
		out.write(output);
		out.flush();
		out.close();
	}
		
	/**
	 * 返回请求结果。
	 * @param status
	 * @param code
	 * @param responseCommand
	 * @return
	 */
	public ResponseCommand returnResult(boolean status,String code,ResponseCommand responseCommand){
		responseCommand.setStatus(status);
		responseCommand.setCode(code);
		return responseCommand;
	}
	
	/**
	 * 返回请求结果。
	 * @param status
	 * @param code
	 * @param object
	 * @param responseCommand
	 * @return
	 */
	public ResponseCommand returnResult(boolean status,String code,Object object,ResponseCommand responseCommand){
		responseCommand.setObject(object);
		responseCommand.setStatus(status);
		responseCommand.setCode(code);
		return responseCommand;
	}
	
	/**
	 * 初始化目录
	 * 
	 * @param path
	 * @throws IOException
	 */
	private void initDirectory(String path) throws IOException {
		File dir = new File(path);
		if (!dir.exists()) {
			FileUtils.forceMkdir(dir);
		}
	}
	
	private String getNewName(String fileName) {
		String newFileName = "Unkonwn";
		if (fileName != null) {
			int index = fileName.lastIndexOf(".");
			if (index != -1){
				newFileName = UUID.randomUUID().toString()+fileName.substring(index);
			}
		}else {
			newFileName = UUID.randomUUID().toString();
		}

		return newFileName;
	}
	
	private String getNewName(String fileName,String fileFlag) {
		String newFileName = "";
		if (StringUtils.isEmpty(fileFlag)) {
			fileFlag = "";
		}
		if (fileName != null) {
			int index = fileName.lastIndexOf(".");
			if (index != -1){
				newFileName = fileFlag + UUID.randomUUID().toString() + fileName.substring(index);
			}
		}else {
			newFileName = fileFlag + newFileName + UUID.randomUUID().toString();
		}

		return newFileName;
	}

	// Parse Content-Disposition header to get the original file name
	private String parseFileName(MultivaluedMap<String, String> headers) {

		String[] contentDispositionHeader = headers.getFirst("Content-Disposition").split(";");

		for (String name : contentDispositionHeader) {

			if ((name.trim().startsWith("filename"))) {

				String[] tmp = name.split("=");

				String fileName = tmp[1].trim().replaceAll("\"","");

				return fileName;
			}
		}
		return "randomName";
	}

	// save uploaded file to a defined location on the server
	private void saveFile(InputStream uploadedInputStream,
		String serverLocation) {

		try {
			OutputStream outpuStream = new FileOutputStream(new File(serverLocation));
			int read = 0;
			byte[] bytes = new byte[1024];

			outpuStream = new FileOutputStream(new File(serverLocation));
			while ((read = uploadedInputStream.read(bytes)) != -1) {
				outpuStream.write(bytes, 0, read);
			}
			outpuStream.flush();
			outpuStream.close();
		} catch (IOException e) {

			e.printStackTrace();
		}
	}

}
